/**
 * 
 */
package com.ibuonline.search.solr.loader;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collection;
import java.util.HashSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wltea.analyzer.cfg.Configuration;
import org.wltea.analyzer.dic.Dictionary;

import com.ibuonline.utils.DbUtils;

/**
 * @author Liuye
 * 
 */
public class IkExtendWordsLoader extends AbstractDbLoader implements DataLoader {
	private static final Logger log = LoggerFactory
			.getLogger(IkExtendWordsLoader.class);
	private long startId = 0;// 行号
	private long endId = 0;// 最大id

	private static final int fetchSize = 50000; // 每次抓取记录条数

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibuonline.search.solr.loader.AbstractDbLoader#load()
	 */
	@Override
	public void load() {
		log.info("Loading IK words from database...");
		endId = getEndId();
		if (endId <= startId) {
			log.info("have no loadable words.");
			return;
		}
		long totalCount = getTotalCount();
		if (totalCount <= 0) {
			log.info("have no loadable words.");
			return;
		}
		Connection conn = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			int pageCount = calcPageCount(totalCount, fetchSize);
			String sql = "SELECT id,word FROM search_word WHERE id BETWEEN ? AND ? LIMIT ?,?";
			conn = dataSource.getConnection();
			stmt = conn.prepareStatement(sql);
			for (int pageNo = 1; pageNo < pageCount + 1; pageNo++) {
				int startIndex = (pageNo - 1) * fetchSize;
				stmt.clearParameters();
				stmt.setLong(1, startId + 1);
				stmt.setLong(2, endId);
				stmt.setLong(3, startIndex);
				stmt.setLong(4, fetchSize);
				rs = stmt.executeQuery();
				proecessResultSet(rs);
			}
			startId = endId;
			log.info("IK words loaded.");
		} catch (SQLException e) {
			log.error("Failed to load words.", e);
		} finally {
			DbUtils.close(conn, stmt, rs);
		}
	}

	private long getTotalCount() {
		Connection conn = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {

			String sql = "SELECT COUNT(id) AS total_count FROM search_word WHERE id BETWEEN ? AND ? ";
			conn = dataSource.getConnection();
			stmt = conn.prepareStatement(sql);
			stmt.setLong(1, startId + 1);
			stmt.setLong(2, endId);
			rs = stmt.executeQuery();
			if (rs.next()) {
				return rs.getLong("total_count");
			} else {
				return 0;
			}
		} catch (SQLException e) {
			log.error("数据库访问异常", e);
		} finally {
			DbUtils.close(conn, stmt, rs);
		}
		return 0;
	}

	private long getEndId() {
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			conn = dataSource.getConnection();
			stmt = conn.createStatement();
			String sql = "SELECT max(id) as max_id FROM search_word";
			rs = stmt.executeQuery(sql);
			if (rs.next()) {
				return rs.getLong("max_id");
			}
		} catch (SQLException e) {
			log.error("开始加载" + getJobName() + "数据异常", e);
		} finally {
			DbUtils.close(conn, stmt, rs);
		}
		return 0;
	}

	@Override
	protected void proecessResultSet(ResultSet rs) throws SQLException {
		Collection<String> words = new HashSet<String>();
		while (rs.next()) {
			String word = rs.getString("word");
			if (word != null && word.trim() != "") {
				words.add(word);
			}
		}
		if (!words.isEmpty()) {
			try {
				Dictionary.initial(Configuration.getInstance());
				Dictionary.getSingleton().addWords(words);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private int calcPageCount(long totalCount, int pageSize) {
		if (totalCount == 0)
			return 0;

		int count = (int) (totalCount / pageSize);
		if (totalCount % pageSize > 0) {
			count++;
		}
		return count;
	}

	@Override
	protected String getJobName() {
		return "词库";
	}

	@Override
	protected String getSql() {
		return null;
	}

}
